Java回溯法: package sun; import java.util.*; public class Knapsack0{ /* 用回溯法解决0-1背包问题 */ private double[] p,w;//分别代表价值和重量 private int n; private double c,bestp,cp,cw; private int x[]; //记录可选的物品 private int[] cx; public Knapsack0(double pp[],double ww[],double cc){ this.p=pp;this.w=ww;this.n=pp.length-1; this.c=cc;this.cp=0;this.cw=0; this.bestp=0; x=new int[ww.length]; cx=new int[pp.length]; } void knapsack(){ backtrack(0); } void backtrack(int i){ if(i>n){ //判断是否到达了叶子节点 if(cp>bestp){ for(int j=0;j<x.length;j++) x[j]=cx[j]; bestp=cp; } return; } if(cw+w[i]<=c){//搜索右子树 cx[i]=1; cw+=w[i]; cp+=p[i]; backtrack(i+1); cw-=w[i]; cp-=p[i]; } cx[i]=0; backtrack(i+1); //检查左子树 } void printResult(){ System.out.println("*****回溯法*****"); System.out.println("*****物品个数:n=5"); System.out.println("*****背包容量:c=10"); System.out.println("*****物品重量数组:ww= {2,2,6,5,4}"); System.out.println("*****物品价值数组:vv= {6,3,5,4,6}"); System.out.println("*****最优值:="+bestp); System.out.println("*****选中的物品是:"); for(int i=0;i<x.length;i++){ System.out.print(x[i]+" "); } } public static void main(String[] args){ double p[]={6,3,5,4,6}; double w[]={2,2,6,5,4}; int maxweight=10; Knapsack0 ks=new Knapsack0(p,w,maxweight); ks.knapsack(); //回溯搜索 ks.printResult(); } } 分支限界法: package sun; public class knapsack1 { static double c; static int n; static double w[]; static double p[]; static double cw; static double cp; static int bestX[]; static MaxHeap heap; //上界函数bound计算结点所相应价值的上界 private static double bound(int i){ double cleft=c-cw; double b=cp; while(i<=n&&w[i]<=cleft){ cleft=cleft-w[i]; b=b+p[i]; i++; } //装填剩余容量装满背包 if(i<=n) b=b+p[i]/w[i]*cleft; return b; } //addLiveNode将一个新的活结点插入到子集树和优先队列中 private static void addLiveNode(double up,double pp,double ww,int lev,BBnode par,boolean ch){ //将一个新的活结点插入到子集树和最大堆中 BBnode b=new BBnode(par,ch); HeapNode node =new HeapNode(b,up,pp,ww,lev); heap.put(node); } private static double MaxKnapsack(){ //优先队列式分支限界法,返回最大价值,bestx返回最优解 BBnode enode=null; int i=1; double bestp=0;//当前最优值 double up=bound(1);//当前上界 while(i!=n+1){//非叶子结点 //检查当前扩展结点的左儿子子结点 double wt=cw+w[i]; if(wt<=c){ if(cp+p[i]>bestp) bestp=cp+p[i]; addLiveNode(up,cp+p[i],cw+w[i],i+1,enode,true); } up=bound(i+1); if(up>=bestp) addLiveNode(up,cp,cw,i+1,enode,false); HeapNode node =(HeapNode)heap.removeMax(); enode=node.liveNode; cw=node.weight; cp=node.profit; up=node.upperProfit; i=node.level; } for(int j=n;j>0;j--){ bestX[j]=(enode.leftChild)?1:0; enode=enode.parent; } return cp; } public static double knapsack(double pp[],double ww[],double cc,int xx[]){ //返回最大值,bestX返回最优解 c=cc; n=pp.length-1; //定义以单位重量价值排序的物品数组 Element q[]=new Element[n]; double ws=0.0; double ps=0.0; for(int i=0;i<n;i++){ q[i]=new Element(i+1,pp[i+1]/ww[i+1]); ps=ps+pp[i+1]; ws=ws+ww[i+1]; } if(ws<=c){ return ps; } p=new double[n+1]; w=new double[n+1]; for(int i=0;i<n;i++){ p[i+1]=pp[q[i].id]; w[i+1]=ww[q[i].id]; } cw=0.0; cp=0.0; bestX = new int[n+1]; heap = new MaxHeap(n); double bestp = MaxKnapsack(); for(int j=0;j<n;j++) xx[q[j].id]=bestX[j+1]; return bestp; } public static void main(String [] args){ double w[]=new double[6]; w[1]=2;w[2]=2;w[3]=6;w[4]=5;w[5]=4; double v[]=new double[6]; v[1]=6;v[2]=3;v[3]=4;v[4]=5;v[5]=6; double c=10; int x[] = new int[6]; double m = knapsack(v,w,c,x); System.out.println("*****分支限界法*****"); System.out.println("*****物品个数:n=5"); System.out.println("*****背包容量:c=10"); System.out.println("*****物品重量数组:w= {2,2,6,5,4}"); System.out.println("*****物品价值数组:v= {6,3,5,4,6}"); System.out.println("*****最优值:="+m); System.out.println("*****选中的物品是:"); for(int i=1;i<=5;i++) System.out.print(x[i]+" "); } } //子空间中节点类型 class BBnode{ BBnode parent;//父节点 boolean leftChild;//左儿子节点标志 BBnode(BBnode par,boolean ch){ parent=par; leftChild=ch; } } class HeapNode implements Comparable{ BBnode liveNode; // 活结点 double upperProfit; //结点的价值上界 double profit; //结点所相应的价值 double weight; //结点所相应的重量 int level; // 活结点在子集树中所处的层次号 //构造方法 public HeapNode(BBnode node, double up, double pp , double ww,int lev){ liveNode = node; upperProfit = up; profit = pp; weight = ww; level = lev; } public int compareTo(Object o) { double xup = ((HeapNode)o).upperProfit; if(upperProfit < xup) return -1; if(upperProfit == xup) return 0; else return 1; } } class Element implements Comparable{ int id; double d; public Element(int idd,double dd){ id=idd; d=dd; } public int compareTo(Object x){ double xd=((Element)x).d; if(d<xd)return -1; if(d==xd)return 0; return 1; } public boolean equals(Object x){ return d==((Element)x).d; } } class MaxHeap{ static HeapNode [] nodes; static int nextPlace; static int maxNumber; public MaxHeap(int n){ maxNumber = (int)Math.pow((double)2,(double)n); nextPlace = 1;//下一个存放位置 nodes = new HeapNode[maxNumber]; } public static void put(HeapNode node){ nodes[nextPlace] = node; nextPlace++; heapSort(nodes); } public static HeapNode removeMax(){ HeapNode tempNode = nodes[1]; nextPlace--; nodes[1] = nodes[nextPlace]; heapSort(nodes); return tempNode; } private static void heapAdjust(HeapNode [] nodes,int s,int m){ HeapNode rc = nodes[s]; for(int j=2*s;j<=m;j*=2){ if(j<m&&nodes[j].upperProfit<nodes[j+1].upperProfit) ++j; if(!(rc.upperProfit<nodes[j].upperProfit)) break; nodes[s] = nodes[j]; s = j; } nodes[s] = rc; } private static void heapSort(HeapNode [] nodes){ for(int i=(nextPlace-1)/2;i>0;--i){ heapAdjust(nodes,i,nextPlace-1); } } } http://zhidao.baidu.com/question/158833086.htmlusing System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace Test01Bag { public partial class Form1 : Form { public Form1() { InitializeComponent(); } public class Product { #region 商品类 /// <summary> /// 商品重量泛型List存储 /// </summary> private List<int> weight = new List<int>(); public List<int> Weight { get{ return weight; } set{ weight = value; } } private List<int> value = new List<int>(); /// <summary> /// 商品价值泛型List存储 /// </summary> public List<int> Value { get { return this.value; } set{ this.value = value; } } private int count; /// <summary> /// 商品数量 /// </summary> public int Count { get { count = weight.Count; return count; } } /// <summary> /// 添加商品信息 /// </summary> /// <param name="w">重量</param> /// <param name="v">价值</param> /// <returns></returns> public int setWeightAddValve(int w, int v) { weight.Add(w); value.Add(v); return weight.Count; } #endregion } public class Bag { #region 背包类 int[,] help = new int[100, 100]; int[] weight = new int[100]; int[] value = new int[100]; int count; int temp; // 背包容量 private int valume; public int Valume { get{ return valume; } set { valume = value; } } private int maxvalue; public int Maxvalue { get { return maxvalue; } set{ maxvalue = value; } } /// <summary> /// 设定容量temp暂存 /// </summary> /// <param name="v"></param> public void setValume(int v) { valume = v; temp = valume; } /// <summary> /// 引入数据 /// </summary> /// <param name="newprd">Product</param> public void setProduct(Product newprd) { count = newprd.Count; weight = newprd.Weight.ToArray(); value = newprd.Value.ToArray(); } /// <summary> /// 买商品 /// </summary> /// <returns></returns> public int buyproduct() { //初始化help表第一行为零 for (int w = 0; w < valume; w++) { help[0, w] = 0; } for (int i = 1; i <= count; i++) { // //初始化help表第一l列为零 help[i, 0] = 0; for (int w = 1; w <= valume; w++) { int temp = w - weight[i - 1]; if (weight[i - 1] <= w) { if (value[i - 1] + help[i - 1, temp] > help[i - 1, w]) { help[i, w] = value[i - 1] + help[i - 1, temp]; } else { help[i, w] = help[i - 1, w]; } } else { help[i, w] = help[i - 1, w]; } } } maxvalue = help[count, valume]; return maxvalue; } /// <summary> /// 显示结果买的商品状态存入ArrayList /// </summary> /// <returns></returns> public ArrayList showResult() { ArrayList result = new ArrayList(); if (weight[0] == help[1, temp]) { result.Add("Buy!"); } else { result.Add("Not Buy!"); } if (count >= 2) { for (int i = count; i <= 2; i--) { if (help[i, temp] == help[i - 1, temp]) { result.Add("Not Buy!"); } else { result.Add("Buy!"); } temp = temp - weight[i - 1]; } } return result; } #endregion } /// <summary> /// 实例化 /// </summary> Product newproduct = new Product(); Bag newbag = new Bag(); int i=1; private void Form1_Load(object sender, EventArgs e) { ///初始化 onit(); } public void onit() { #region 程序初始化 //清空 newproduct.Value.Clear(); newproduct.Weight.Clear(); newbag.Valume = 0; lstboxResult.Items.Clear(); #endregion } /// <summary> /// 存储商品信息函数 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnAddProduct_Click(object sender, EventArgs e) { #region 添加商品信息 try { int w = Convert.ToInt32(txtWeight.Text); int v = Convert.ToInt32(txtValue.Text); newproduct.setWeightAddValve(w, v); i++; label1.Text = "请输入商品(" + i.ToString() + ")的体积:"; label3.Text = "请输入商品(" + i.ToString() + ")的价值:"; txtWeight.Text = ""; txtValue.Text = ""; } catch { MessageBox.Show("你的输入有错误,请重新输入!"); return; } #endregion } /// <summary> /// 问题解决函数 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnToBuy_Click(object sender, EventArgs e) { #region 解决背包问题 try { int i = 1; int v = Convert.ToInt32(txtValume.Text); newbag.setValume(v); txtValume.Text = ""; newbag.setProduct(newproduct); int x = newbag.buyproduct(); lblMaxvalue.Text = "最大价值为:" + newbag.buyproduct().ToString(); ArrayList result = newbag.showResult(); int f = result.Count; foreach (string str in result) { string message = "商品" + i.ToString() + "--------" + str; lstboxResult.Items.Add(message); i++; } onit(); } catch { MessageBox.Show("你的输入有错误,请重新输入!"); return; } #endregion } } }http://zhidao.baidu.com/question/101148292.html
回朔法、分支限界法解0-1背包问题程序, Java, C#
最新推荐文章于 2021-03-11 05:29:07 发布